package com.example.demo.service.impl;

import com.alibaba.fastjson.JSON;
import com.example.demo.service.ActivitiRunService;
import com.example.demo.service.dto.TaskDto;
import org.camunda.bpm.engine.HistoryService;
import org.camunda.bpm.engine.RepositoryService;
import org.camunda.bpm.engine.RuntimeService;
import org.camunda.bpm.engine.TaskService;
import org.camunda.bpm.engine.history.HistoricActivityInstance;
import org.camunda.bpm.engine.history.HistoricTaskInstance;
import org.camunda.bpm.engine.impl.persistence.entity.HistoricActivityInstanceEntity;
import org.camunda.bpm.engine.repository.Deployment;
import org.camunda.bpm.engine.runtime.ActivityInstance;
import org.camunda.bpm.engine.runtime.Execution;
import org.camunda.bpm.engine.task.Comment;
import org.camunda.bpm.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @program: camunda-springboot-example
 * @description:
 * @author: chenxf
 * @create: 2022-01-18 15:43
 **/
@Service
public class ActivitiRunServiceImpl implements ActivitiRunService {
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private HistoryService historyService;
    @Autowired
    private RepositoryService repositoryService;

    @Override
    public void cancelProcess(String processInstanceId) {
        ActivityInstance activity = runtimeService.getActivityInstance(processInstanceId);
        runtimeService.createProcessInstanceModification(processInstanceId)
                //关闭相关任务
                .cancelActivityInstance(activity.getId())
                .setAnnotation("发起人撤回")
                //启动目标活动节点
                .startBeforeActivity("root")
                .execute();
    }

    @Override
    public String deploy(String name) {
        Deployment deployment=repositoryService.createDeployment()
                .name(name)
                .addClasspathResource("process/"+name)
                .deploy();
        System.out.println("流程部署id：" + deployment.getId());
        System.out.println("流程部署名称：" + deployment.getName());
        return deployment.getId();
    }

    @Override
    public String startProcess(Map<String, Object> params) {
        Execution execution = runtimeService.startProcessInstanceByKey(params.get("key").toString(), params);
        System.out.println("实例启动成功，实例ID：" + execution.getProcessInstanceId());
        return "实例启动成功，实例ID：" + execution.getProcessInstanceId();
    }

    @Override
    public List<TaskDto> candiUserTask(String assignee) {
        List<Task> tasks = taskService.createTaskQuery()
                .taskCandidateUser(assignee)
                .orderByTaskCreateTime().asc()
                .active().list();
        return tasks.stream().map(e-> {
            TaskDto dto=new TaskDto(e);
            dto.setTaskId(e.getId());
            dto.setMap(taskService.getVariables(e.getId()));
            return dto;
        }).collect(Collectors.toList());
    }

    @Override
    public String candiUserFinishedTask(String assignee) {
        List<HistoricTaskInstance> historicTaskInstances = historyService.createHistoricTaskInstanceQuery()
                .taskAssignee(assignee)
                .orderByHistoricActivityInstanceStartTime().desc()
                .finished().list();
        return JSON.toJSONString(historicTaskInstances);
    }

    @Override
    public List<TaskDto> assignTask(String assignee) {
        List<Task> tasks = taskService.createTaskQuery()
                .taskAssignee(assignee)
                .orderByTaskCreateTime().asc()
                .active().list();
        return tasks.stream().map(e-> {
            TaskDto dto=new TaskDto(e);
            dto.setTaskId(e.getId());
            dto.setMap(taskService.getVariables(e.getId()));
            return dto;
        }).collect(Collectors.toList());
    }

    @Override
    public String approveTask(String taskId,String assignee, boolean passed,String comment) {
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        if (!ObjectUtils.isEmpty(task)) {
            Map<String, Object> approveVariables = new HashMap<>(1);
            approveVariables.put("passed", passed);
            approveVariables.put("comment",comment);
            this.taskService.claim(taskId, assignee);
            taskService.createComment(taskId, task.getProcessInstanceId(), comment);
            taskService.complete(taskId, approveVariables);
            System.out.println("任务审核完成，审核"
                    + (passed ? "通过" : "拒绝"));
            return "任务审核完成，审核"
                    + (passed ? "通过" : "拒绝");
        }
        System.out.println("无任务可审核");


        return "无任务可审核";
    }

    @Override
    public String testQueryHistory(String instanceId) {
        List<HistoricActivityInstance> activityInstanceList= historyService.createHistoricActivityInstanceQuery()
                .processInstanceId(instanceId).orderByHistoricActivityInstanceStartTime().asc().list();
        for (HistoricActivityInstance hi : activityInstanceList) {
            HistoricActivityInstanceEntity entity=(HistoricActivityInstanceEntity) hi;
            //if("userTask".equals(hi.getActivityType())){
                System.out.println("");
                System.out.println("===================-===============");
                System.out.println(hi.getStartTime());
                System.out.println(hi.getAssignee());
                System.out.println(hi.getActivityId());
                System.out.println(hi.getActivityName());
                System.out.println(entity.getActivityInstanceState());
                 List<Comment> taskComments = taskService.getTaskComments(hi.getTaskId());
                taskComments.stream().forEach(e->{
                    System.out.println("comment:"+e.getFullMessage());
                });
                System.out.println(hi.getTaskId());
                System.out.println(hi.getProcessDefinitionId());
                System.out.println(hi.getProcessInstanceId());
                System.out.println("===================-===============");
                System.out.println("");
           // }


        }
        return JSON.toJSONString(activityInstanceList);
    }

}
